package org.dromara.system.service.impl.pay;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.BusinessException;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.WechatConfig;
import org.dromara.system.domain.bo.InitGetMachineBo;
import org.dromara.system.domain.bo.InitPayMemberBo;
import org.dromara.system.domain.common.JsApiOrderModel;
import org.dromara.system.service.IWechatConfigService;
import org.dromara.system.util.JsonUtil;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.InetAddress;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class wechatGzhPay extends AbstractPayService {

    private final static String OPENID_PATH = "https://api.weixin.qq.com/sns/jscode2session";
    private final static String VIP_NOTIFY_URL = "http://121.40.66.143:4330/system/memberRecords/openMemberShip/callBak/wxPay";
    private final static String GET_MACHINE_NOTIFY_URL = "http://121.40.66.143:4330/system/userGetMachineRecords/getMachine/callBak/wxPay";
    private final IWechatConfigService wechatConfigService;

    @Override
    public String initPayMember(InitPayMemberBo initPayMemberBo) {
        log.info("initPayMemberBo={}", JSONUtil.toJsonStr(initPayMemberBo));
        BigDecimal memberPrice = initPayMemberBo.getSysUserMemberConfig().getMemberPrice();
        SysUser sysUser = initPayMemberBo.getSysUser();
        WechatConfig wechatConfig = wechatConfigService.lambdaQuery().eq(WechatConfig::getUserId, sysUser.getOneId()).one();
        BusinessException.isNull(wechatConfig, "代理商微信参数未配置！");
        String openId = initPayMemberBo.getOpenId();
        BusinessException.isTrue(StrUtil.isBlank(openId), "OPENID不能为空！");
        BigDecimal round = NumberUtil.round(NumberUtil.mul(memberPrice, 100), 0, RoundingMode.HALF_UP);
        try {
            Map<String, String> params = JsApiOrderModel
                .builder()
                .appid(wechatConfig.getAppId())
                .mch_id(wechatConfig.getMchId())
                .nonce_str("微信支付")
                .body("微信支付")
                .out_trade_no(initPayMemberBo.getMemberRecordsBo().getNo())
                // 支付金额注意是以分为单位的
                .total_fee(String.valueOf(round))
                .spbill_create_ip(InetAddress.getLocalHost().getHostAddress())
                .notify_url(VIP_NOTIFY_URL)
                .trade_type(TradeType.JSAPI.getTradeType())
                .openid(openId)
                .attach(JSONUtil.toJsonStr(initPayMemberBo.getMemberRecordsBo()))
                .build()
                .createSign(wechatConfig.getMchKey(), SignType.MD5);
            String orderPay = JSON.toJSONString(params);
            String xmlResult = WxPayApi.pushOrder(false, JsonUtil.toMap(orderPay));
            log.info("initPayMember=={}", xmlResult);
            Map<String, String> resultMap = WxPayKit.xmlToMap(xmlResult);
            if (StringUtils.equals(resultMap.get("return_code"), "SUCCESS")) {
                String prepayId = resultMap.get("prepay_id");
                Map<String, String> packageParams = WxPayKit.prepayIdCreateSign(prepayId, wechatConfig.getAppId(),
                    wechatConfig.getMchKey(), SignType.MD5);
                return JSONUtil.toJsonStr(packageParams);
            }
        } catch (Exception e) {
            BusinessException.isTrue(Boolean.TRUE, "微信拉起支付异常！");
        }
        return "";
    }

    @Override
    public String initPayGetMachine(InitGetMachineBo initPayMemberBo) {
        log.info("initPayGetMachine入参={}", JSONUtil.toJsonStr(initPayMemberBo));
        SysUser sysUser = initPayMemberBo.getSysUser();
        WechatConfig wechatConfig = wechatConfigService.lambdaQuery().eq(WechatConfig::getUserId, sysUser.getOneId()).one();
        BusinessException.isNull(wechatConfig, "代理商微信参数未配置！");
        String openId = initPayMemberBo.getOpenId();
        BusinessException.isTrue(StrUtil.isBlank(openId), "OPENID为空！");
        BigDecimal round = NumberUtil.round(NumberUtil.mul(initPayMemberBo.getGetMachinePrice(), 100), 0, RoundingMode.HALF_UP);
        try {
            Map<String, String> params = JsApiOrderModel
                .builder()
                .appid(wechatConfig.getAppId())
                .mch_id(wechatConfig.getMchId())
                .nonce_str("微信支付")
                .body("微信支付")
                .out_trade_no(initPayMemberBo.getSysUserGetMachineRecordsBo().getNo())
                // 支付金额注意是以分为单位的
                .total_fee(String.valueOf(round))
                .spbill_create_ip(InetAddress.getLocalHost().getHostAddress())
                .notify_url(GET_MACHINE_NOTIFY_URL)
                .trade_type(TradeType.JSAPI.getTradeType())
                .openid(openId)
                .attach(Convert.toStr(initPayMemberBo.getSysUserGetMachineRecordsBo().getId()))
                .build()
                .createSign(wechatConfig.getMchKey(), SignType.MD5);
            String orderPay = JSON.toJSONString(params);
            String xmlResult = WxPayApi.pushOrder(false, JsonUtil.toMap(orderPay));
            log.info("initPayGetMachine=={}", xmlResult);
            Map<String, String> resultMap = WxPayKit.xmlToMap(xmlResult);
            if (StringUtils.equals(resultMap.get("return_code"), "SUCCESS")) {
                String prepayId = resultMap.get("prepay_id");
                Map<String, String> packageParams = WxPayKit.prepayIdCreateSign(prepayId, wechatConfig.getAppId(),
                    wechatConfig.getMchKey(), SignType.MD5);
                return JSONUtil.toJsonStr(packageParams);
            }
        } catch (Exception e) {
            BusinessException.isTrue(Boolean.TRUE, "微信拉起支付异常！");
        }
        return "";
    }
}
